import { smc } from "../../../../common/ecs/SingletonModuleComp";
import { Role } from "../../../../role/Role";
import { BattleTriggerEvent, Effect } from "../../../scene/model/BattleEnum";
import { BattleType } from "../../../scene/SceneEvent";
import { EffectDamage } from "../../model/report/EffectDamage";
import { ISkillReport } from "../../model/report/ISkillReport";
import { Skill } from "../../Skill";
import { RoleSelector } from "./RoleSelector";
import { RoleState } from "./RoleState";

/** 战斗事件触发 */
export class BattleEventTrigger {
      /** 战斗开始 */
      static onBattleStart(type: BattleType){
        var roles: Role[] = [];

        switch (type) {
            case BattleType.Scene:
                roles = smc.scene.MapModelRole.roles;
                break;
            case BattleType.Boss:
                //roles = smc.boss.BossMapModelRole.roles;
                console.warn(`###战斗开始### Boss 战斗未实现`);
                break;
            case BattleType.Tower:
                //roles = smc.tower.TowerMapModelRole.roles;
                console.warn(`###战斗开始### 塔战斗未实现`);

                break;
            default:
                break;
        }
        roles.forEach(role => {
            role.RoleModelSkill.passives.forEach(s => {
                s.cast(role, role, BattleTriggerEvent.BattleStart);
            });

            role.RoleModelSkill.qiMap.forEach(s => {
                s.cast(role, role, BattleTriggerEvent.BattleStart);
            });
        });
    }
    /** 敌方BUFF添加完成时触发 */
    static onEnemyBuffAdded(target: Role, buffId: number, num: number) {
        var roles: Role[] = [];

        switch (target.RoleModel.battleType) {
            case BattleType.Scene:
                roles = smc.scene.MapModelRole.roles;
                break;
            case BattleType.Boss:
               // roles = smc.boss.BossMapModelRole.roles;
                console.warn(`###敌方BUFF添加完成时触发### Boss todo战斗未实现`);
                break;
            case BattleType.Tower:
                // roles = smc.tower.TowerMapModelRole.roles;
                console.warn(`###敌方BUFF添加完成时触发### todo塔战斗未实现`);
                break;
            default:
                break;
        }
        roles.forEach(role => {
            if(target.RoleModel.myTeam != role.RoleModel.myTeam){
                role.RoleModelSkill.passives.forEach(s => {
                    s.cast1(target, role, BattleTriggerEvent.EnemyBuffAdded, buffId, num);
                });
            }
        });
    }
    /** 回合开始 */
    static onRoundStart(type: BattleType) {
        var roles: Role[] = [];

        switch (type) {
            case BattleType.Scene:
                roles = smc.scene.MapModelRole.roles;
                break;
            case BattleType.Boss:
                // roles = smc.boss.BossMapModelRole.roles;
                console.warn(`###回合开始### Boss todo战斗未实现`);
                break;
            case BattleType.Tower:
                // roles = smc.tower.TowerMapModelRole.roles;
                console.warn(`###回合开始### todo塔战斗未实现`);
                break;
            default:
                break;
        }
        roles.forEach(role => {
            // 检查技能释放者BUFF是否触发
            if(!RoleState.isDie(role)){
                role.RoleModelBattle.buffs.forEach(buff => {
                    buff.cast(BattleTriggerEvent.RoundStart);
                });
                role.RoleModelSkill.passives.forEach(skill => {
                    skill.cast(role, role, BattleTriggerEvent.RoundStart);
                });
            }
        });
    }

    /** 回合结束 */
    static onRoundEnd(type: BattleType) {
        var roles: Role[] = [];

        switch (type) {
            case BattleType.Scene:
                roles = smc.scene.MapModelRole.roles;
                break;
            case BattleType.Boss:
                //roles = smc.boss.BossMapModelRole.roles;
                console.warn(`###回合结束### Boss 战斗未实现`);
                break;
            case BattleType.Tower:
                //roles = smc.tower.TowerMapModelRole.roles;
                console.warn(`###回合结束### 塔战斗未实现`);

                break;
            default:
                break;
        }
        roles.forEach(role => {
            // 回合结束检测被动技能
            if(!RoleState.isDie(role)){
                role.RoleModelSkill.passives.forEach(skill => {
                    skill.cast(role, role, BattleTriggerEvent.RoundEnd);
                });
            }
        });
    }
    /**角色行动前 */

    static onActionBefore(caster: Role) {
        caster.RoleModelSkill.passives.forEach(s => {
            s.cast(caster, null!, BattleTriggerEvent.ActionBefore);
        });
    }
    /**角色行动后 */

    static onActionAfter(caster: Role) {
        caster.RoleModelSkill.passives.forEach(s => {
            s.cast(caster, null!, BattleTriggerEvent.ActionAfter);
        });
       
        caster.RoleModelBattle.buffs.forEach(buff => {
            buff.cast(BattleTriggerEvent.ActionAfter);
        });
        caster.RoleModelSkill.qiMap.forEach(skill => {
            skill.cast(caster, caster, BattleTriggerEvent.ActionAfter);
        });
    }


    /** 友军护盾消失时 */
    static onFriendShieldOver(caster: Role) {
        var modelRole!: any;
        switch (caster.RoleModel.battleType) {
            case BattleType.Scene:
                modelRole = smc.scene.MapModelRole
                break;
            case BattleType.Boss:
                // modelRole = smc.boss.BossMapModelRole
                console.warn(`###友军护盾消失时### Boss todo战斗未实现`);
                break;
            case BattleType.Tower:
                // modelRole = smc.tower.TowerMapModelRole
                console.warn(`###友军护盾消失时### todo塔战斗未实现`);
                break;
            default:
                break;
        }
        var roles: Role[] = [];
        if(caster.RoleModel.myTeam){
            roles = modelRole.roles;
        }else{
            roles = modelRole.enemys;
        }

        roles.forEach(role => {
            if(!RoleState.isDie(role)){
                role.RoleModelSkill.passives.forEach(skill => {
                    skill.cast(role, role, BattleTriggerEvent.FriendShieldOver);
                });
            }
        });
    }
    /** 友军释放技能时 */

    static onFriendSkillCasting(caster: Role, skill: Skill) {
        var modelRole!: any;
        switch (caster.RoleModel.battleType) {
            case BattleType.Scene:
                modelRole = smc.scene.MapModelRole
                break;
            case BattleType.Boss:
                // modelRole = smc.boss.BossMapModelRole
                console.warn(`###友军释放技能时### Boss todo战斗未实现`);
                break;
            case BattleType.Tower:
                // modelRole = smc.tower.TowerMapModelRole
                console.warn(`###友军释放技能时### todo塔战斗未实现`);
                break;
            default:
                break;
        }
        var roles: Role[] = [];
        if(caster.RoleModel.myTeam){
            if(skill.SkillModel.table.skill_type == 2){
                roles = modelRole.roles;
            }
        }else{
            if(skill.SkillModel.table.skill_type == 2){
                roles = modelRole.enemys;
            }
        }

        roles.forEach(role => {
            if(!RoleState.isDie(role)){
                role.RoleModelSkill.passives.forEach(skill => {
                    skill.cast(role, role, BattleTriggerEvent.FriendSkillCasting);
                });
            }
        });
    }



    /** 格挡时 */
    static onBlock(isr: ISkillReport, target: Role, effect: Effect) {
        this.trigger(BattleTriggerEvent.Block, isr, target, target, effect);
    }

    /** 目标受到伤害前 */ /** 技能效果计算前 */
    static onCastBefore(isr: ISkillReport, target: Role, effect: EffectDamage) {
        this.trigger(BattleTriggerEvent.CastBefore, isr, target, isr.caster, effect);
    }
    /** 目标受到伤害后 */ /** 技能效果计算后 */

    static onCastAfter(isr: ISkillReport, target: Role, effect: EffectDamage) {
        if (isr.caster && RoleState.isDie(isr.caster)) {
            // 技能施放者死亡
            this.trigger(BattleTriggerEvent.SelfDie, isr, target, isr.caster, effect);
            RoleSelector.youfangRoles(isr.caster).forEach(element => {
                this.trigger(BattleTriggerEvent.OtherDie, isr, element, element, effect);
            });
            RoleSelector.difangRoles(isr.caster).forEach(element => {
                this.trigger(BattleTriggerEvent.EnemyDie, isr, element, element, effect);
            });
        }
        else {
            this.trigger(BattleTriggerEvent.CastAfter, isr, target, isr.caster, effect);
        }
    }
    /** 技能效果前 */

    static onHitBefore(isr: ISkillReport, target: Role, effect: EffectDamage) {
        this.trigger(BattleTriggerEvent.HitBefore, isr, target, target, effect);
    }
    /** 技能效果后 */

    static onHitAfter(isr: ISkillReport, target: Role, effect: EffectDamage) {
        if (RoleState.isDie(target)) {
            // 受击者死亡
            this.trigger(BattleTriggerEvent.SelfDie, isr, target, target, effect);
            RoleSelector.youfangRoles(target).forEach(element => {
                this.trigger(BattleTriggerEvent.OtherDie, isr, element, element, effect);
            });
            RoleSelector.difangRoles(target).forEach(element => {
                this.trigger(BattleTriggerEvent.EnemyDie, isr, element, element, effect);
            });
        }
        else {
            this.trigger(BattleTriggerEvent.HitAfter, isr, target, target, effect);
        }
    }



    /**
     * 触发事件
     * @param event         触发事件
     * @param isr           技能施放战报
     * @param target        技能受击
     * @param check_target  验证身上技能或BUFF的目标
     */

    private static trigger(event: BattleTriggerEvent, isr: ISkillReport, target: Role, check_target: Role = null!, effect: Effect = null!) {
        if (!check_target) {
            return
        }

        if (!isr.caster) {
            return
        }
        // 检查技能施放者其它被动技能是否触发
        check_target.RoleModelSkill.passives.forEach(s => {
            s.cast(isr.caster, target, event);
        });

        // 检查技能施放者其它气技能是否触发
        check_target.RoleModelSkill.qiMap.forEach(s => {
            s.cast(isr.caster, target, event);
        });

        // 检查技能释放者BUFF是否触发
        check_target.RoleModelBattle.buffs.forEach(buff => {
            buff.cast(event, effect);
        });
    }



}